package com.work.studio.views;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.work.studio.utils.TimerUtils;

import java.io.File;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * app更新类
 */
public class AppDownLoadManager {


    private static AppDownLoadManager appDownLoadManager = null;

    private Context context;//上下文参数
    private DownloadManager downloadManager;//下载类
    private AppDownloadManagerListener listener;//监听接口
    private Disposable disposable;
    private String downUrl;//下载地址
    private String downDir;//下载文件夹
    private String downName;//文件名称
    private long downloadId;//下载文件唯一标识
    private String filePath;//下载文件的根路径
    private String TAG = this.getClass().getSimpleName();

    public AppDownLoadManager setDownUrl(String downUrl) {
        this.downUrl = downUrl;
        return this;
    }

    public AppDownLoadManager setDownDir(String downDir) {
        this.downDir = downDir;
        return this;
    }

    public AppDownLoadManager setDownName(String downName) {
        this.downName = downName;
        return this;
    }

    private AppDownLoadManager(Context context) {

        this.context = context;
        this.downUrl = "";
        this.downDir = "";
        this.downName = "";
    }
    private AppDownLoadManager(Context context, String downUrl, String downDir, String downName) {

        this.context = context;
        this.downUrl = downUrl;
        this.downDir = downDir;
        this.downName = downName;
    }

    public static AppDownLoadManager getInstance(Context context, String downUrl, String downDir, String downName) {

        if (appDownLoadManager == null) {
            appDownLoadManager = new AppDownLoadManager(context, downUrl, downDir, downName);
        }

        return appDownLoadManager;
    }

    public static AppDownLoadManager getInstance(Context context) {

        if (appDownLoadManager == null) {
            appDownLoadManager = new AppDownLoadManager(context, null, null, null);
        }

        return appDownLoadManager;
    }


    public AppDownLoadManager startDown() {

        try {

            if (TextUtils.isEmpty(downUrl)) {
                if (listener != null) {
                    listener.onFailed("下载地址不能为空");
                }
                return this;
            }
            if (TextUtils.isEmpty(downDir)) {
                downDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
            }
            if (TextUtils.isEmpty(downName)) {
                downName = getFileNameByUrl(downUrl);
            }

            //创建下载请求类
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));
            //移动网络情况下是否允许漫游
            request.setAllowedOverRoaming(false);
            //不设置表示WiFi以及MobileNet都可以
//            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI)
            /**
             * VISIBILITY_VISIBLE=0；只是显示在下载中
             * VISIBILITY_VISIBLE_NOTIFY_COMPLETED=1； 下载中显示以及下载完成也显示
             * VISIBILITY_HIDDEN=2； 不显示
             * VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION=3；只在下载完成后显示
             *
             */
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            //标题
            request.setTitle("第三方在线");
            //下载进度
            request.setVisibleInDownloadsUi(true);
            //7.0以上的系统适配
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                request.setRequiresDeviceIdle(false);
                request.setRequiresCharging(false);
            }
//            request.setDescription("新版本V1.0");
            Log.e(TAG, "downUrl:"+downUrl+"\ndownDir:"+downDir+"\ndownName");
            //创建下载文件
            File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), downName);
            //设置下载存放的文件
            request.setDestinationUri(Uri.fromFile(file));
            //文件根路径
            filePath = file.getAbsolutePath();
            Log.e(TAG, "downUrl:"+downUrl+"\ndownDir:"+downDir+"\ndownName:"+downName+"\nfilePath:"+filePath);
            if (downloadManager == null) {
                downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
            }

            //将创建下载任务，并加入下载队列，加入队列成功之后会返回一个任务id根据这个ID可以取消任务，重启任务，获取下载文件等等
            if (listener != null) {
                listener.onPrepare();
            }
            downloadId = downloadManager.enqueue(request);
            interval();
            //注册广播，监听下载状态
            context.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "startDown:"+e.getMessage());
        }

        return this;
    }

    /**
     * 轮询
     */
    private void interval() {
        try {

            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose();
            }
            disposable = null;

            disposable = Observable.interval(0, 500, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {

                            downLoadProgress();

                        }
                    });

        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "interval Error:"+e.getMessage());
        }
    }



    /**
     * 监听接口
     */
    public interface AppDownloadManagerListener {
        void onPrepare();//准备开始

        void onProgress(long size, long total);//准备开始

        void onSuccess(String path);//下载成功

        void onFailed(String error);//下载失败
    }
    public void setListener(AppDownloadManagerListener listener) {
        this.listener = listener;
    }


    /**
     * 通过URL获取文件名
     *
     * @param url
     * @return
     */
    private String getFileNameByUrl(String url) {
        String filename = null;
        try {
            filename = url.substring(url.lastIndexOf("/") + 1);
            filename = filename.substring(0, filename.indexOf("?") == -1 ? filename.length() : filename.indexOf("?"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (TextUtils.isEmpty(filename)) {

            filename = TimerUtils.getCurrentTime()+".apk";
        }
        return filename;
    }



    BroadcastReceiver receiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {

            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downloadId);
            Cursor cursor = downloadManager.query(query);
            if (cursor.moveToFirst()) {

                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                switch (status) {
                        //下载暂停
                    case DownloadManager.STATUS_PAUSED:
                        Log.e(TAG, "下载暂停");
                        break;
                        //下载延迟
                    case DownloadManager.STATUS_PENDING:
                        Log.e(TAG, "下载延迟");
                        break;
                        //下载进行中
                    case DownloadManager.STATUS_RUNNING:
                        Log.e(TAG, "下载进行中");
                        break;
                        //下载成功
                    case DownloadManager.STATUS_SUCCESSFUL:
                        Log.e(TAG, "下载成功");
                        if (listener !=null) {
                            listener.onSuccess(filePath);
                        }
                        cursor.close();
                        context.unregisterReceiver(receiver);
                        if (disposable != null && !disposable.isDisposed()) {
                            disposable.dispose();
                        }
                        disposable = null;
                        downLoadProgress();
                        break;
                        //下载失败
                    case DownloadManager.STATUS_FAILED:
                        Log.e(TAG, "下载失败");
                        if (listener !=null) {
                            listener.onFailed("下载失败");
                        }
                        cursor.close();
                        context.unregisterReceiver(receiver);
                        if (disposable != null && !disposable.isDisposed()) {
                            disposable.dispose();
                        }
                        disposable = null;
                        break;
                }
            }

        }
    };


    /**
     * 查询进度
     */
    private void downLoadProgress() {
        try {

            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downloadId);
            Cursor cursor = downloadManager.query(query);

            if (cursor.moveToFirst()) {


                long bytesDownload = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                String descrition = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION));
                String id = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
                String localUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                String mimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
                String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));
                String status_ = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                long totalSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

                Log.e(TAG, "bytesDownload:" + bytesDownload);
                Log.e(TAG, "descrition:" + descrition);
                Log.e(TAG, "id:" + id);
                Log.e(TAG, "localUri:" + localUri);
                Log.e(TAG, "mimeType:" + mimeType);
                Log.e(TAG, "title:" + title);
                Log.e(TAG, "status:" + status_);
                Log.e(TAG, "totalSize:" + totalSize);

                if (listener != null) {
                    listener.onProgress(bytesDownload, totalSize);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "downLoadProgress Error:"+e.getMessage());
        }
    }
}
